package com.lin.missyou.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.swing.plaf.synth.DefaultSynthStyle;

import javax.swing.text.html.Option;
import java.util.*;

@Component
public class JwtToken {

    private static String jwtKey;
    private static Integer expiredTime;
    private static Integer defaultScope = 0;

    @Value("${missyou.security.jwt-key}")
    public void setJwtKey(String jwtKey) {
        JwtToken.jwtKey = jwtKey;
    }

    @Value("${missyou.security.token-expired-in}")
    public void setExpiredTime(Integer expiredTime) {
        JwtToken.expiredTime = expiredTime;
    }


    public static String makeToken(Long uid, Integer scope) {
        return JwtToken.getToken(uid, scope);
    }

    public static String makeToken(Long uid) {
        return JwtToken.getToken(uid, JwtToken.defaultScope);
    }

    private static String getToken(Long uid, Integer scope) {
        // jjwt
        // auth0
//        用来加密数字签名的密钥
        Algorithm salt = Algorithm.HMAC256(JwtToken.jwtKey);
        Map<String, Date> map = JwtToken.calculateExpiredIssues();
        // 7200
        // 3.12 12:00  + 7200 = ExpiresDate

        return JWT.create()
                .withClaim("uid", uid)
                .withClaim("scope", scope)
                .withExpiresAt(map.get("expiredTime"))
                .withIssuedAt(map.get("now"))
                .sign(salt);
    }

    private static Map<String, Date> calculateExpiredIssues() {
        Map<String, Date> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        Date now = calendar.getTime();
        calendar.add(Calendar.SECOND, JwtToken.expiredTime);
        map.put("now", now);
        map.put("expiredTime", calendar.getTime());
        return map;
    }

    public static Optional<Map<String, Claim>> getClaims(String token) {
        //解析验证token
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(JwtToken.jwtKey)).build();
        // 解密后的DecodedJWT对象，可以读取token中的数据。
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        }
/*        catch (TokenExpiredException e) {
            // 或者对比过期时间
            return Optional.empty();
        } */
        catch (JWTVerificationException e) {
//            token携带的签名无效或者 Claim不匹配，就会抛出 JWTVerificationException 异常
            return Optional.empty();
        }
        return Optional.of(jwt.getClaims());
    }

    public static  Boolean verify(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(JwtToken.jwtKey)).build();
            verifier.verify(token);
        }catch (JWTVerificationException e) {
            return false;
        }
        return true;
    }
}
